﻿using BZ.Camera.MindVision;
using HalconDotNet;
using HslCommunication;
using NDK.Module.Model;
using NDK.Motion.BLL;
using NDK.Motion.MachineResources;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
using VisionPlatform;

namespace NDK.Module.StationLogic
{
    public abstract class StationLogic : StationLogicBase
    {
        public bool isOK;

        public MVController CCD = null;

        public HImage hImage_Cam = null;

        public int CaptureImage1Count;

        public OperateResult ret_Write = null;

        public VisionManager.Engine eng = null;

        public ConcurrentQueue<string[]> SNQueue;
        public ConcurrentQueue<MeasureProduct> DataQueue1;
        public ConcurrentQueue<MeasureProduct> DataQueue2;

        public bool 工位要料 = false;
        public bool 工位完成 = false;

        public bool GRR工位要料 = false;
        public bool GRR工位完成 = false;

        public readonly Dictionary<int, string> AlgorithmNameDic = new Dictionary<int, string> { { -1, "" }, { 0, "_Min" }, { 1, "_Nor" }, { 2, "_Max" } };

        public override void Init ()
        {
            base.Init();
            工位要料 = false;
            工位完成 = false;

            GRR工位要料 = false;
            GRR工位完成 = false;
        }

        /// <summary>
        /// 气缸同步运动函数
        /// </summary>
        /// <param name="isWork">Work Or Home</param>
        /// <param name="cylinders">1.当前需要控制的气缸 2.是否屏蔽</param>
        /// <returns></returns>
        public bool CylinderMethod(bool isWork, params (DoubleDriveCylinder, bool)[] cylinders)
        {
            List<Task<(string, bool)>> tasks = new List<Task<(string, bool)>>();
            foreach (var item in cylinders)
            {
                tasks.Add(Task.Run(() => Work(item)));
            }
            Task.WaitAll(tasks.ToArray());

            var taskbool = tasks.FindAll(task => task.Result.Item2 == true);
            if (taskbool.Count > 0)
            {
                string mes = string.Empty;
                taskbool.ForEach(x => mes += $"{x.Result.Item1} ");
                return AlarmPause("气缸异常", $"{mes}{(isWork ? "动点" : "原点")}位异常,请检查", "调试气缸信号", "重新检测", "忽略报警，继续运行") != DialogResult.OK;
            }
            return true;


            (string, bool) Work((DoubleDriveCylinder, bool) cylinder)
            {
                (string, bool) re = (cylinder.Item1.Name, false);
                if (cylinder.Item2)
                {
                    _ = isWork ? cylinder.Item1.Work() : cylinder.Item1.Home();
                    bool IsTimeOut = isWork ? cylinder.Item1.WaitWork(Common.气缸等待时间) : cylinder.Item1.WaitHome(Common.气缸等待时间);
                    re.Item2 = IsTimeOut;
                }
                return re;
            }
        }

        /// <summary>
        /// 真空同步动作函数
        /// </summary>
        /// <param name="isON"> On or Off</param>
        /// <param name="vacuums">1.真空输出 2.真空反馈 3.是否屏蔽</param>
        /// <returns></returns>
        public bool VacuumMethod(bool isON, params (OutputSetting, InputSetting, bool)[] vacuums)
        {
            List<Task<(string, bool)>> tasks = new List<Task<(string, bool)>>();
            foreach (var item in vacuums)
            {
                tasks.Add(Task.Run(() => Work(item)));
            }
            Task.WaitAll(tasks.ToArray());
            var isOK = tasks.FindAll(x => x.Result.Item2 == true);
            if (isOK.Count > 0)
            {
                string mes = string.Empty;
                tasks.ForEach(x => mes += $"{x.Result.Item1}{(isON ? "打开" : "关闭")}异常 ");
                return AlarmPause("吸真空报警", $"{mes}，请检查", "调试真空信号", "重新检测", "忽略报警，继续运行") != DialogResult.OK;
            }
            return true;

            (string, bool) Work((OutputSetting, InputSetting, bool) vacuum)
            {
                (string, bool) re = (vacuum.Item2.Name, false);
                if (vacuum.Item3)
                {
                    _ = isON ? vacuum.Item1.ON() : vacuum.Item1.OFF();
                    if (Common.是否检测信号)
                    {
                        bool isWork = isON ? vacuum.Item2.WaitON(3000) : vacuum.Item2.WaitOFF(3000);
                        re.Item2 = isWork;
                    }
                }
                return re;
            }
        }

        /// <summary>
        /// PLC同步写入函数
        /// </summary>
        /// <param name="station">当前写入工站</param>
        /// <param name="plcs">1.写入地址 2.True Or False</param>
        /// <returns></returns>
        public bool PLCWriteMethod(string station, params (string, bool?, short?)[] plcs)
        {
            List<Task<(string, bool)>> tasks = new List<Task<(string, bool)>>();
            foreach (var item in plcs)
            {
                if(item.Item2 != null)
                {
                    tasks.Add(Task.Run(() => Machine.OmronPLC.Write(item.Item1, (bool)item.Item2).IsSuccess ? (string.Empty, true) : (item.Item1, false)));
                }
                else if(item.Item3 != null)
                {

                    tasks.Add(Task.Run(() => Machine.OmronPLC.Write(item.Item1, (short)item.Item3).IsSuccess ? (string.Empty, true) : (item.Item1, false)));
                }
            }
            Task.WaitAll(tasks.ToArray());
            var IsOk = tasks.FindAll(x => x.Result.Item2 == false);
            if (IsOk.Count > 0)
            {
                string mes = string.Empty;
                tasks.ForEach(x => mes += $"{x.Result.Item1} ");
                return AlarmPause("写PLC异常", $"{station},写入地址", "写PLC异常，请检查", "重新写入", "忽略报警，继续运行") != DialogResult.OK;
            }
            return true;
        }
    }
}
